using System;
using System.Collections;
using Input;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;

public class Player : MonoBehaviour
{
	public bool isBusy = false;
	
	[Header("Dash info")] 
	public float dashDuration = 1.5f;


	public bool debugState;


	private Animator anim;

	public MovementComponent movement { get; private set; }
	public PlayerController controller { get; private set; }
	
	public PlayerStateMachine stateMachine { get; private set; }
	
	public PlayerState_Idle idleState { get; private set; }
	public PlayerState_Move moveState { get; private set; }
	public PlayerState_Jump jumpState { get; private set; }
	public PlayerState_Air airState { get; private set; }
	public PlayerState_WallSlide wallSlideState{ get; private set; }
	public PlayerState_WallJump WallJumpState { get; private set; }
	public PlayerState_PrimaryAttack PrimaryAttackState { get; private set; }
	public PlayerState_Dash dashState { get; private set; }
	
	
	private void Awake()
	{
		stateMachine = new PlayerStateMachine();
		
		idleState = new PlayerState_Idle(this, stateMachine, "Idle");
		moveState = new PlayerState_Move(this, stateMachine, "Move");
		jumpState = new PlayerState_Jump(this, stateMachine, "Jump");
		airState = new PlayerState_Air(this, stateMachine, "Jump");
		wallSlideState = new PlayerState_WallSlide(this, stateMachine, "WallSlide");
		WallJumpState = new PlayerState_WallJump(this, stateMachine, "Jump");
		PrimaryAttackState = new PlayerState_PrimaryAttack(this, stateMachine, "Attack");
		dashState = new PlayerState_Dash(this, stateMachine, "Dash");
	}
	
	private void Start()
	{
		anim = GetComponentInChildren<Animator>();
		movement = GetComponent<MovementComponent>();
		controller = GetComponent<PlayerController>();
		
		stateMachine.Initialize(idleState);
	}
	


	private void Update()
	{
		stateMachine.currentState.Update();
		CheckForDashInput();
	}

	public IEnumerator BusyFor(float seconds)
	{
		isBusy = true;
		yield return new WaitForSeconds(seconds);
		isBusy = false;
	}

	public void AnimationTrigger() => stateMachine.currentState.AnimationFinishTrigger();
	
	private void CheckForDashInput()
	{
		if (controller.wasDash())
		{
			stateMachine.ChangeState(dashState);
		}
	}


	public void Movement(Vector3 direction)
	{
		movement.AddMovement(direction);
	}

	public bool SetAnim<T>(string key, T value)
	{
		if (typeof(T) == typeof(bool))
		{
			var v =  (bool)(object)value;
			anim.SetBool(key, v);
			return true;
		}

		if (typeof(T) == typeof(int))
		{
			var v = (int)(object)value;
			anim.SetInteger(key, v);
			return true;
		}

		if (typeof(T) == typeof(float))
		{
			var v = (float)(object)value;
			anim.SetFloat(key, v);
			return true;
		}
		
		return false;
	}





	
}
